﻿// SystemApiCmd.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <string>
#include <vector>
#include <iostream>
#include "windows.h"

#include <map>
#include <locale>
#include <codecvt>

inline std::wstring u8to_wstring(const std::string& input)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.from_bytes(input);
}
inline std::string to_u8string(const std::wstring& input)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.to_bytes(input);
}

std::wstring ansi2wstring(std::string str)
{
    std::wstring result;
    //获取缓冲区大小，并申请空间，缓冲区大小按字符计算  
    int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
    TCHAR* buffer = new TCHAR[len + 1];
    //多字节编码转换成宽字节编码  
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
    buffer[len] = '\0';             //添加字符串结尾  
    //删除缓冲区并返回值  
    result.append(buffer);
    delete[] buffer;
    return result;
}

std::string wstring2ansi(std::wstring wstr)
{
    std::string result; 
    //获取缓冲区大小，并申请空间，缓冲区大小事按字节计算的  
    int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
    char* buffer = new char[len + 1];
    //宽字节编码转换成多字节编码  
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
    buffer[len] = '\0';
    //删除缓冲区并返回值  
    result.append(buffer);
    delete[] buffer;
    return result;
}

int Api_WritePrivateProfileString(const std::vector<std::wstring>& argVec)
{
    int argCount = argVec.size();
    if (argCount < 5)
    {
        std::wcout << L"##ERROR##1" << std::endl;
        std::wcout << L"参数：WritePrivateProfileString sGroup sKey sValue sFile" << std::endl;
        return 1;
    }

    std::wstring sGroup = argVec[2];
    std::wstring sKey = argVec[3];
    std::wstring sValue = argVec[4];
    std::wstring sFile = argVec[5];
    bool bRet3 = ::WritePrivateProfileString(sGroup.data(), sKey.data(), sValue.data(), sFile.data());
    if (bRet3)
    {
        std::wcout << L"##OK##" << std::endl;
        return 0;
    }
    else
    {
        std::wcout << L"##ERROR##2" << std::endl;
        return 2;
    }
}
int Api_GetPrivateProfileString(const std::vector<std::wstring>& argVec)
{
    int argCount = argVec.size();
    if (argCount < 5)
    {
        std::wcout << L"##ERROR##1" << std::endl;
        std::wcout << L"参数：GetPrivateProfileString sGroup sKey sDefault sFile" << std::endl;
        return 1;
    }

    std::wstring sGroup = argVec[2];
    std::wstring sKey = argVec[3];
    std::wstring sDefault = argVec[4];
    std::wstring sFile = argVec[5];
    std::wstring sValue(1024, 0);
    DWORD length = ::GetPrivateProfileString(sGroup.data(), sKey.data(), sDefault.data(), (LPWSTR)sValue.data(), sValue.size()-1, sFile.data());
    sValue.resize(length);
    std::wcout << sValue;
    return 0;
}


int main(int argc, char* argv[], char* envp[])
{
    std::wcout.imbue(std::locale("chs"));

    if (argc < 2)
    {
        std::wcout << L"##ERROR##-1" << std::endl;
        std::wcout << L"命令：SystemApiCmd API [argv] [u8]" << std::endl;
        std::wcout << L"argv是API的参数列表" << std::endl;
        std::wcout << L"最后一个参数如果是u8，则认为传入的是UTF8字符，否则默认为ANSI" << std::endl;
        return -1;
    }

    bool isUtf8 = false;
    std::string argLast = argv[argc - 1];
    if (argLast.compare("u8") == 0)
    {
        isUtf8 = true;
    }
    //保存参数列表
    int argCount = isUtf8 ? argc-1 : argc;
    std::vector<std::wstring> argVec;
    for (int i = 0; i < argCount; i++)
    {
        std::wstring argStr = isUtf8 ? u8to_wstring(argv[i]) : ansi2wstring(argv[i]);
        argVec.push_back(argStr);
    }
    //保存环境变量
    std::map<std::wstring, std::wstring> envMap;
    for (int k = 0; envp[k] != 0; k++)
    {
        std::wstring strEnv = isUtf8 ? u8to_wstring(envp[k]) : ansi2wstring(envp[k]);
        auto pos = strEnv.find_first_of(L"=");
        std::wstring strKey = strEnv.substr(0, pos);
        std::wstring strValue = strEnv.substr(pos+1);
        envMap.insert(std::pair<std::wstring, std::wstring>(strKey, strValue));
    }

    if (argVec[1] == L"WritePrivateProfileString")
    {
        return Api_WritePrivateProfileString(argVec);
    }

    if (argVec[1] == L"GetPrivateProfileString")
    {
        return Api_GetPrivateProfileString(argVec);
    }

    return 0;
}
